/* Given a tree with n nodes, we want to find one or more nodes such that the
 * total distance from all nodes to this node is minimized. If n = 1 or n = 2,
 * the solution is trivial. Therefore below we discuss the case for n >= 3.
 *
 * First we note that a leaf node, u, cannot be optimal. That is because if 
 * we pick its adjacent node, v, the increase in distance by 1 constributed by
 * u is offset by the decrease in distance by 1 contributed by v. However, 
 * all other nodes are closer to v than to u, thus the overall distance is
 * reduced. Therefore we can remove any leaf node u from consideration by
 * 'merging' it into its adjacent node v.
 *
 * To generalize this idea and proceed, we associate with each node u two 
 * attributes: subtree-size and subtree-cost. Subtree-size is the number of
 * nodes in the subtree merged into u, including u itself. Initially, the
 * subtree-size of all nodes are 1. Subtree-cost is the total distance from
 * all nodes in the subtree to u. Initially the subtree-cost of all nodes
 * are set to 0.
 *
 * After each step of merging, we examine the remaing nodes. If there are just
 * two nodes left, the solution is trivial. Otherwise, there are at least two
 * outstanding leaf nodes. Take any two of the leave nodes, u and u', and let
 * u be the one with a smallest subtree-size. Then we merge u into its
 * adjacent node v. To show that this is correct, note that the extra distance
 * contributed by u and its children is equal to its subtree-size, which is 
 * offset by the reduction in distance contributed by u'. All other nodes are
 * closer to v than to u. In addition, the total distance is reduced by 1 due 
 * to v, so the overall cost is strictly improved.
 */

#include <stdio.h>
#include <memory.h>
#include <algorithm>

template <class vid_t, class eid_t, int MaxN, int MaxM>
class adjacency_list
{
    struct node
    {
        vid_t degree;       /* numer of adjacent nodes */
        eid_t first_edge;   /* id of the first edge adjacent to the node */
    };

    struct edge
    {
        vid_t v1;           /* id of first vertex; 0=deleted */
        vid_t v2;           /* id of second vertex */
        eid_t next1;        /* id of next edge adjacent to v1, 0=last */
        eid_t next2;        /* id of next edge adjacent to v2, 0=last */
    };

    node   nodes[MaxN+1];   /* nodes[0] is not used */
    size_t num_nodes;
    edge   edges[MaxM+1];   /* edges[0] is not used */
    size_t num_edges;

public:
    adjacency_list() : num_nodes(0), num_edges(0) { }

    void resize(size_t size)
    {
        num_nodes = size;
        memset(nodes, 0, sizeof(nodes[0]) * num_nodes);
        num_edges = 0;
    }

    size_t size() const { return num_nodes; }

    eid_t add_edge(vid_t v1, vid_t v2)
    {
        eid_t e = (eid_t)++num_edges;
        nodes[v1].degree++;
        nodes[v2].degree++;

        edges[e].v1 = v1;
        edges[e].v2 = v2;
        edges[e].next1 = nodes[v1].first_edge;
        edges[e].next2 = nodes[v2].first_edge;
        nodes[v1].first_edge = e;
        nodes[v2].first_edge = e;
        return e;
    }

    void remove_edge(eid_t e)
    {
        if (edges[e].v1 != 0) /* edge exists */
        {
            nodes[edges[e].v1].degree--;
            nodes[edges[e].v2].degree--;
            edges[e].v1 = 0;
        }
    }

    size_t degree(vid_t u) const { return nodes[u].degree; }

    vid_t next_neighbor(vid_t u, eid_t &e)
    {
        eid_t *pnext = (e == 0)? &nodes[u].first_edge :
                       (edges[e].v2 == u)? &edges[e].next2 : &edges[e].next1;
        e = *pnext;
        while (e)
        {
            if (edges[e].v1 != 0) /* edge exists */
                return (edges[e].v1 ^ edges[e].v2 ^ u);

            /* Update the link to skip deleted edge. */
            *pnext = e = (edges[e].v2 == u)? edges[e].next2 : edges[e].next1;
        }
        return 0;
    }
};

typedef unsigned short vid_t;   /* node id type (1-based) */
typedef unsigned short eid_t;   /* edge id type (1-based) */

struct node_data
{
    vid_t size;                 /* subtree-size, including itself */
    int   cost;                 /* subtree-cost */
};

static adjacency_list<vid_t, eid_t, 50000, 49999> tree;
static node_data nodes[50001];
static vid_t leaves[50000];     /* ids of leaf nodes */
static int num_leaves;

static void solve()
{
    int num_nodes, current, resistance, i;
    scanf("%d %d %d", &num_nodes, &current, &resistance);

    tree.resize(num_nodes);
    for (i = 1; i <= num_nodes; i++)
    {
        nodes[i].size = 1;
        nodes[i].cost = 0;
    }
    for (i = 1; i <= num_nodes - 1; i++)
    {
        int u, v;
        scanf("%d %d", &u, &v); /* 1-based node index */
        tree.add_edge((vid_t)u, (vid_t)v);
    }

    /* If there's only one node, easy. */
    if (num_nodes <= 1)
    {
        printf("0\n1\n");
        return;
    }

    /* Find leaf nodes. */
    num_leaves = 0;
    for (i = 1; i <= num_nodes; i++)
    {
        if (tree.degree((vid_t)i) == 1)
            leaves[num_leaves++] = (vid_t)i;
    }

    /* Iteratively merge leaf nodes until there are two nodes left. */
    while (num_nodes > 2)
    {
        vid_t u1, u2, u;

        /* Check the last two leaf nodes and pick the one with smaller 
         * subtree-size. */
        u2 = leaves[num_leaves-2];
        u1 = leaves[num_leaves-1];
        u = (nodes[u1].size <= nodes[u2].size)? u1 : u2;
        if (u == u2)
            leaves[num_leaves-2] = u1;
        num_leaves--;

        /* Merge u into its (only) adjacent node, v. */
        eid_t e = 0;
        vid_t v = tree.next_neighbor(u, e);
        nodes[v].size += nodes[u].size;
        nodes[v].cost += nodes[u].cost + nodes[u].size;
#if 0
        printf("Merge %d into %d\n", u, v);
#endif

        /* Remove edge (v, u) from the tree. */
        tree.remove_edge(e);
        --num_nodes;

        /* Append v to the leaf list if it becomes a leaf. */
        if (tree.degree(v) == 1)
            leaves[num_leaves++] = v;
    }

    /* Now the only two nodes left are in leaves[0..1]. */
    {
        vid_t u = leaves[0], v = leaves[1];
        int cost = nodes[u].cost + nodes[v].cost + 
                   std::min(nodes[u].size, nodes[v].size);
        printf("%lld\n", (unsigned long long)cost*current*current*resistance);
        if (nodes[u].size == nodes[v].size)
            printf("%d %d\n", std::min(u, v), std::max(u, v));
        else
            printf("%d\n", (nodes[u].size > nodes[v].size)? u : v);
    }
}

int main()
{
    int num_cases;
    scanf("%d", &num_cases);
    while (num_cases--)
    {
        solve();
        printf("\n");
    }
    return 0;
}
